import algorithms.importance.degree_centrality
import algorithms.importance.betweenness_centrality

def computeDRI(gr):
    skew = algorithms.importance.degree_centrality.getNormalizedDegreeSkew(gr)
    minskew = 0.0
    n = float(gr.getNumNodes())
    maxskew = (0.5 * n - 1.0)/n
    DRI = 1 - (skew - minskew)/(maxskew - minskew)
    return DRI

def computeInDRI(gr):
    skew = algorithms.importance.degree_centrality.getNormalizedInDegreeSkew(gr)
    minskew = 0.0
    n = float(gr.getNumNodes())
    maxskew = 0.5 - 1.0/n
    DRI = 1 - (skew - minskew)/(maxskew - minskew)
    return DRI

def computeOutDRI(gr):
    skew = algorithms.importance.degree_centrality.getNormalizedOutegreeSkew(gr)
    minskew = 0.0
    n = float(gr.getNumNodes())
    maxskew = (0.5 * n - 1.0)/n
    DRI = 1 - (skew - minskew)/(maxskew - minskew)
    return DRI

def computeNBRI(gr = None, nl = None, apsp = None):
    skew = algorithms.importance.betweenness_centrality.getNormalizedNodeBetweennessSkew(gr, nl, apsp)
    minskew = 0.0
    n = 0
    if gr:
        n = float(gr.getNumNodes())
    else:
        n = float(len(nl))
    maxskew = 1.0 - 1.0/n
    NBRI = 1 - (skew - minskew)/(maxskew - minskew)
    return NBRI

def getConnectivitySequence(gr = None, app = None):
    if gr:
        app = algorithms.paths.paths.getAllPaths(gr)        
    connectivity = {}
    conn = 0
    for src, destdict in app.iteritems():
        for dest, pl in destdict.iteritems():
            if not pl:
                continue            
            conn = pl.getNumPaths()
            connectivity[src + ' ' + dest] = conn
    return connectivity

def worstcaseEdgeConnectivityRI(gr):
    app = algorithms.paths.paths.getAllPaths(gr)
    connv = []
    for src, destdict in app.iteritems():
        for dest, pl in destdict.iteritems():
            if not pl:
                return 0.0
            conn = pl.getNumPaths()
            if conn < 2:
                return 0.0
            connv.append(conn)
    robustness = float(min(connv) - 1)/float(gr.getNumNodes() - 2)
    del connv[:]
    return robustness

def avgcaseEdgeConnectivityRI(gr):
    app = algorithms.paths.paths.getAllPaths(gr)
    connv = []
    for src, destdict in app.iteritems():
        for dest, pl in destdict.iteritems():
            if not pl:
                return 0.0
            conn = pl.getNumPaths()
            connv.append(conn)    
    avgconn = float(sum(connv))/float(gr.getNumNodes() * (gr.getNumNodes() - 1))
    robustness = float(avgconn - 1)/float(gr.getNumNodes() - 2)
    del connv[:]
    return robustness

def getAvgVertexCutsetSize(gr):
    el = gr.getEdgeList()
    for i in range(100):
        pass        

def getAvgEdgeCutsetSize(gr):
    pass

def getConnSeq(gr = None, app = None):
    return [v for v in getConnectivitySequence(gr = gr, app = app).values()]

def computeRobustness(gr = None, nl = None, el = None, apsp = None):
    #return computeDRI(gr)
    return computeNBRI(gr, nl, apsp)

